import { Injectable } from "@nestjs/common";
import { ObjectId } from "mongodb"

export interface Conditions {
    $eq?: any;
    $ne?: any;
    $gt?: any;
    $gte?: any;
    $lt?: any;
    $lte?: any;
    $exists?: boolean;
    $in?: any[];
    $nin?: any[];
    $type?: string | 'double' | 'string';
    $and?: any[];
    build?: () => Conditions
}

@Injectable()
export class Util {
    formatTimestamp(date, fmt = 'yyyy-MM-dd hh:mm:ss'): string {

        if (!date) return "";
        let nowDate = new Date();
        let opt = {
            "M+": nowDate.getMonth() + 1, //月份
            "d+": nowDate.getDate(), //日
            "h+": nowDate.getHours(), //小时
            "m+": nowDate.getMinutes(), //分
            "s+": nowDate.getSeconds(), //秒
            "q+": Math.floor((nowDate.getMonth() + 3) / 3), //季度
            "S": nowDate.getMilliseconds(), //毫秒
        };
        let regex = new RegExp("(y+)");
        if (regex.test(fmt)) {
            let fmtMatch = fmt.match(regex);
            fmt = fmt.replace(fmtMatch[1], (nowDate.getFullYear() + "").substr(4 - fmtMatch[1].length));
        }
        for (let k in opt) {
            let regex = new RegExp("(" + k + ")");
            if (regex.test(fmt)) {
                let fmtMatch = fmt.match(regex);
                fmt = fmt.replace(fmtMatch[1], (fmtMatch[1].length == 1) ? (opt[k]) : (("00" + opt[k]).substr(("" + opt[k]).length)));
            }
        }
        return fmt;

    };

    _ = (() => {
        const createCondition = (key?: string) => {
            let conditions: Conditions = {};

            const wrapObjectIdIfNeeded = (value: any) => {
                // 判断 key 是否为 '_id'，如果是，则处理 ObjectId
                if (key === '_id') {
                    if (Array.isArray(value)) {
                        return value.map(v => ObjectId.isValid(v) ? new ObjectId(v) : v);
                    }
                    return ObjectId.isValid(value) ? new ObjectId(value) : value;
                }
                return value;
            };

            return {
                eq(value) {
                    conditions.$eq = wrapObjectIdIfNeeded(value);
                    return this;
                },

                ne(value) {
                    conditions.$ne = wrapObjectIdIfNeeded(value);
                    return this;
                },

                gt(value) {
                    conditions.$gt = wrapObjectIdIfNeeded(value);
                    return this;
                },

                gte(value) {
                    conditions.$gte = wrapObjectIdIfNeeded(value);
                    return this;
                },

                lt(value) {
                    conditions.$lt = wrapObjectIdIfNeeded(value);
                    return this;
                },

                lte(value) {
                    conditions.$lte = wrapObjectIdIfNeeded(value);
                    return this;
                },

                in(values) {
                    conditions.$in = wrapObjectIdIfNeeded(values);
                    return this;
                },

                nin(values) {
                    conditions.$nin = wrapObjectIdIfNeeded(values);
                    return this;
                },

                exists(value) {
                    conditions.$exists = value;
                    return this;
                },

                type(value) {
                    conditions.$type = value;
                    return this;
                },

                build() {
                    return conditions;
                }
            };
        };

        return {
            eq(value) {
                return createCondition('_id').eq(value); // 默认处理 '_id'
            },

            ne(value) {
                return createCondition('_id').ne(value); // 默认处理 '_id'
            },

            gt(value) {
                return createCondition('_id').gt(value); // 默认处理 '_id'
            },

            gte(value) {
                return createCondition('_id').gte(value); // 默认处理 '_id'
            },

            lt(value) {
                return createCondition('_id').lt(value); // 默认处理 '_id'
            },

            lte(value) {
                return createCondition('_id').lte(value); // 默认处理 '_id'
            },

            in(values) {
                return createCondition('_id').in(values); // 默认处理 '_id'
            },

            nin(values) {
                return createCondition('_id').nin(values); // 默认处理 '_id'
            },

            exists(value) {
                return createCondition().exists(value);
            },

            type(value) {
                return createCondition().type(value);
            }
        };
    })();

    sleep(duration: number = 1000): Promise<void> {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve()
            }, duration)
        })
    }

    // 过滤对象
    filterObject<T>(obj: T, keys: (keyof T)[], include: boolean): Partial<T> {
        return Object.keys(obj).reduce((filtered, key) => {
            if (keys.includes(key as keyof T)) {
                if (include) {
                    // 如果 include 为 true, 返回指定的字段
                    filtered[key as keyof T] = obj[key as keyof T];
                }
            } else if (!include) {
                // 如果 include 为 false, 过滤掉指定的字段
                filtered[key as keyof T] = obj[key as keyof T];
            }
            return filtered;
        }, {} as Partial<T>);
    }

    // 多维数组对象扁平化
    flattenArray(arr: any[], property: string): any[] {
        return Array.from(new Set(arr.flatMap(item => item[property])));
    }

    buildTree(data: any[], treeProps: { id: string; parent_id: string; children: string }) {
        const map = {};
        const roots = [];

        // 使用 treeProps.id 创建一个 map，方便快速查找每个菜单项
        data.forEach(item => {
            map[item[treeProps.id]] = { ...item, [treeProps.children]: [] };
        });
        // 遍历数据，将每个节点挂载到其父节点的 children 数组中
        data.forEach(item => {
            if (!item[treeProps.parent_id]) {
                // 如果没有父节点，说明是根节点
                roots.push(map[item[treeProps.id]]);
            } else {
                // 如果有父节点，将当前项添加到父节点的 children 数组中
                if (map[item[treeProps.parent_id]]) {
                    map[item[treeProps.parent_id]][treeProps.children].push(map[item[treeProps.id]]);
                }
            }
        });

        const cleanChildren = (nodes: any[]) => {
            return nodes.map(node => {
                const { [treeProps.children]: children, ...rest } = node;
                if (children && children.length > 0) {
                    return { ...rest, [treeProps.children]: cleanChildren(children) }; // 保留非空 children
                }
                const { [treeProps.children]: _, ...cleanedNode } = node; // 移除空的 children
                return cleanedNode; // 返回处理后的节点
            });
        };

        return cleanChildren(roots);
    }
}